﻿using CTP.CRM.Application.Dtos.Demo;
using CTP.CRM.Core;
using CTP.CRM.Core.Common.Attributes;
using CTP.CRM.Core.Common.Dto;
using CTP.CRM.Core.Common.Enums;
using CTP.CRM.Core.PublicMethords;
using CTP.CRM.Core.SqlSugar;
using CTP.CRM.Repository;
using CTP.CRM.Repository.Demo.Entitys;
using CTP.CRM.Repository.Demo.Services;
using CTP.CRM.Repository.Demo.ValueObjects;
using DotNetCore.CAP;
using Dtmcli;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using MySqlConnector;
using Volo.Abp;
using Volo.Abp.Application.Services;

namespace CTP.CRM.Application.Services.Demo
{
    /// <summary>
    /// 接口请求完整样例
    /// </summary>
    [ApiExplorerSettings(GroupName = "Demo")]
    public class InterFaceDemoService : ApplicationService, ICapSubscribe
    {
        #region 构造函数
        private readonly IDemoRepository _demoRepository;
        //private readonly ILoggerHelper _loggerHelper;
        //private readonly ISalesLeadMongoRepository _salesLeadMongoRepository;
        //private readonly IHttpClientProxy<ICustomerService> _customerService;

        public InterFaceDemoService(IDemoRepository demoRepository)
        {
            _demoRepository = demoRepository;

        }
        #endregion

        const string webhook = "https://open.feishu.cn/open-apis/bot/v2/hook/2db4cf41-24f4-4fd2-9fe6-d9888e95a934";
        [AllowAnonymous]
        [HttpGet("CRM/SagaTest1")]
        public async Task<UnifyDtmResultDto> SagaTest(IdBaseDto request, [FromServices] IBranchBarrierFactory _barrierFactory, [FromServices] HttpContext httpContext)
        {

            LogHelper.SendNotice("CRM方法-开始执行");

            var branchBarrier = _barrierFactory.CreateBranchBarrier(httpContext.Request.Query);

            try
            {
                var conn = new MySqlConnection(SqlsugarScopeBasic.GetContextSafely("default").Ado.Connection.ConnectionString);

                await branchBarrier.Call(conn, async (tx) =>
                {
                    LogHelper.SendNotice("CRM子事务-开始执行");

                    var data = await _demoRepository.MyGetByIdAsync(request.Id);
                    if (data == null)
                        throw new BusinessException("未找到指定数据下的任何信息！");


                    data.Description = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff");
                    await _demoRepository.UpdateAsync(data);


                });
            }
            catch (InvalidDataException ex)
            {
                LogHelper.SendNotice("CRM子事务-失败" + ex.Message, webhook);
                return new UnifyDtmResultDto(false);
            }
            LogHelper.SendNotice("CRM子事务-成功");
            return new UnifyDtmResultDto(true);
        }

        /// <summary>
        /// 获取系统
        /// </summary>
        /// <returns></returns>
        [HttpGet("Demo/GetCurrentSystem")]
        [AllowAnonymous]
        public string GetCurrentSystem()
        {
            return "天鹏";
        }

        [AllowAnonymous]
        [HttpGet("CRM/SagaTest2")]
        public async Task<UnifyDtmResultDto> SagaTest2(UnifyDtmResultDto data)
        {
            LogHelper.SendNotice("执行了CRM反向操作" + data.ToJson(), webhook);

            return new UnifyDtmResultDto(true);
        }


        [NonAction]
        [CapSubscribe("CTP.crm.customerChangeLock", Group = "test")]
        public async Task<object> Consumer(DemoInput request)
        {
            //这里需要特别注意，因为CAP有重试机制，所以业务处理要考虑幂等性，千万千万注意！！
            Console.WriteLine("第一个分布式事务消费者");
            request.Description = "执行到了";
            return request;
        }


        #region 增删改 
        /// <summary> 
        /// 增删改 
        /// </summary>  
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("InterFace/Edit")]
        public async Task<LongIdBaseDto> Edit(DemoInput input)
        {
            var res = new LongIdBaseDto();

            if (input.Option == OptionType.新增)
            {
                var entity = ObjectMapper.Map<DemoInput, DemoEntity>(input);
                res.Id = await _demoRepository.InsertReturnIdentityAsync(entity);
            }
            else if (input.Option == OptionType.修改 || input.Option == OptionType.删除)
            {

                var demoInfo = await _demoRepository.MyGetByIdAsync(input.Id);
                if (demoInfo == null)
                {
                    //校验数据是否存在...
                    throw new BusinessException(message: "未找到指定编号下的数据");
                }

                res.Id = demoInfo.Id;
                if (input.Option == OptionType.删除)
                {
                    //await _demoRepository.DeleteAsync(demoInfo);  //真删除  

                    //软删除
                    demoInfo.IsDeleted = true;
                    await _demoRepository.UpdateAsync(demoInfo);
                }
                else
                {
                    var entity = ObjectMapper.Map(input, demoInfo);
                    await _demoRepository.UpdateAsync(entity);
                }
            }
            return res;
        }

        #endregion

        #region 局部更新最佳实践
        /// <summary>
        /// 局部更新最佳实践
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="BusinessException"></exception>
        [HttpPost("InterFace/UpdatePartColumns")]
        public async Task<IdBaseDto> UpdatePartColumns(DemoInput input)
        {
            var demoInfo = await _demoRepository.MyGetByIdAsync(input.Id);
            if (demoInfo == null)
            {
                //校验数据是否存在...
                throw new BusinessException(message: "未找到指定编号下的数据");
            }

            //更新同时忽略某几项参数
            await _demoRepository.UpdatePartColumns(demoInfo);

            return new IdBaseDto() { Id = input.Id };
        }
        #endregion

        #region 分页查询接口
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("InterFace/GetListByPage")]
        public async Task<UnifyPageResultDto<GetDemoListByPageOutput>> GetListByPage(GetDemoListByPageInput input)
        {
            //分页时返回值统一用 PageResultDto<> 类型
            var list = await _demoRepository.GetListByPage(input.PageSize, input.PageIndex, input.Name);

            var res = ObjectMapper.Map<UnifyPageResultDto<DemoEntity>, UnifyPageResultDto<GetDemoListByPageOutput>>(list);

            return res;
        }
        #endregion

        #region 入参转换
        /// <summary>
        /// 入参转换
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("InterFace/InputToValueObject")]
        public async Task<List<GetDemoListByPageOutput>> InputToValueObject(GetDemoListByPageInput input)
        {
            var obj = ObjectMapper.Map<GetDemoListByPageInput, DemoValueObject>(input);
            var list = await _demoRepository.InputToValueObject(obj);

            var res = ObjectMapper.Map<List<DemoEntity>, List<GetDemoListByPageOutput>>(list);
            return res;
        }
        #endregion

        #region 原生sql

        /// <summary>
        /// 原生sql
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        [HttpPost("InterFace/OriginalSql")]
        public async Task<UnifyPageResultDto<DemoValueObject>> OriginalSql(DemoValueObject obj)
        {
            var list = await _demoRepository.OriginalSql(obj);
            return list;
        }

        #endregion

        #region 自定义返回结果格式
        /// <summary>
        /// 自定义返回结果格式
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("Demo/CustomerResult")]
        [CustomerResult]
        public async Task<MyCustomerResultOutput> GetListAsync()
        {
            /*
                说明：
                    理论上我们有全公司级别的返回值约定，不管是前端调后端，还是后端微服务间的调用，都应完全遵循该规范。
                    但不排除有些特殊情况下，必须要返回自定义格式的场景。
             */

            var res = new MyCustomerResultOutput();
            res.Code = "200";
            res.Message = "这是一个自定义返回结果";

            return res;
        }
        #endregion

        #region 约定类型下返回null
        /// <summary>
        /// 约定类型下返回null
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("Demo/ReturnNull")]
        public async Task<MyCustomerResultOutput> ReturnNull()
        {
            MyCustomerResultOutput res = null;
            return res;
        }
        #endregion

        #region 
        /// <summary>
        /// 没有返回值
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("Demo/WithoutReturnObject")]
        public async Task<UnifyResultDto> WithoutReturnObject()
        {
            return null;
        }
        #endregion

        #region 主从关系实体存储
        /// <summary>
        /// 主从关系实体存储
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        [HttpPost("InterFace/EntityRelationSave")]
        public async Task<UnifyResultDto> EntityRelationSave(DemoDetailSaveInput input)
        {
            var obj = ObjectMapper.Map<DemoDetailSaveInput, DemoEntity>(input);
            var res = await _demoRepository.EntityRelationSave(obj);

            return new UnifyResultDto(res);
        }

        #endregion

        #region 数据缓存
        /// <summary>
        /// 数据缓存
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("InterFace/GetDataCache")]
        public async Task<DemoEntity> GetDataCache(IdBaseDto input)
        {
            var res = await _demoRepository.GetDataCache(input.Id);
            return res;
        }
        #endregion

        #region 切换数据库
        /// <summary>
        /// 切换数据库
        /// </summary>
        /// <param name="input"></param>
        /// <param name="_canalRepository"></param>
        /// <returns></returns>
        [HttpPost("InterFace/ChangeDB")]
        public async Task<DemoEntity> ChangeDB(IdBaseDto input, [FromServices] ICanalRepository _canalRepository)
        {
            var db1 = await _demoRepository.MyGetByIdAsync(input.Id);
            var db2 = await _canalRepository.GetById1(input.Id);

            return null;
        }
        #endregion

        #region 日志测试

        /// <summary>
        /// 添加日志
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("InterFace/AddLogger")]
        public async Task<bool> AddLogger(int id)
        {
            //await _loggerHelper.AddOptionLog(new AddLoggerInput
            //{
            //    TableType = TableTypeEnums.客户,
            //    Id = id + string.Empty,
            //    LogType = LogType.人工,
            //    Content = "日志测试内容....",
            //    UserName = "测试",
            //    UserId = 1,
            //    UserAccount = "test"
            //});

            return await Task.FromResult(true);
        }

        

        #endregion



        #region MongoDB销售线索

        /// <summary>
        /// 销售线索
        /// </summary>
        /// <returns></returns>
        [HttpPost("InterFace/SalesLeadTest")]
        public async Task<bool> SalesLeadTest()
        {
            //var entity = new SalesLeadMongoEntity();
            //entity.Id = new MongoDB.Bson.ObjectId("63eb780ca34b5fad0f3bed24");
            //entity.ModuleId = 1;
            //entity.CreateUserId = CurrentUserRequest.CurrentUser.UserId;
            //entity.List = new List<SalesLeadMongoDocument>
            //{
            //    new SalesLeadMongoDocument {
            //        FieldId = 1,
            //        FieldName = "客户名称",
            //        Value = "AAA1"
            //    },
            //    new SalesLeadMongoDocument {
            //        FieldId = 2,
            //        FieldName = "创建时间",
            //        Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
            //    }
            //};

            //entity.List = new List<SalesLeadMongoDocument>
            //{
            //    new SalesLeadMongoDocument {
            //        FieldId = 1,
            //        FieldName = "客户名称",
            //        Value = "BBB"
            //    },
            //    new SalesLeadMongoDocument {
            //        FieldId = 2,
            //        FieldName = "创建时间",
            //        Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
            //    },
            //    new SalesLeadMongoDocument {
            //        FieldId = 3,
            //        FieldName = "业务员",
            //        Value = "李四"
            //    }
            //};

            //entity.List = new List<SalesLeadMongoDocument>
            //{
            //    new SalesLeadMongoDocument {
            //        FieldId = 3,
            //        FieldName = "业务员",
            //        Value = "王五"
            //    },
            //    new SalesLeadMongoDocument {
            //        FieldId = 1,
            //        FieldName = "客户名称",
            //        Value = "CCC"
            //    },
            //    new SalesLeadMongoDocument {
            //        FieldId = 2,
            //        FieldName = "创建时间",
            //        Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
            //    },
            //    new SalesLeadMongoDocument {
            //        FieldId = 4,
            //        FieldName = "联系方式",
            //        Value = "18588888888"
            //    }
            //};

            // await _salesLeadMongoRepository.SaveOneAsync(entity);

            var userIds = new List<int> { 5798 };
          //  var list = await _salesLeadMongoRepository.GetListAsync(t => t.ModuleId == 1 && userIds.Contains(t.CreateUserId));

           // var salesLeadEntity = await _salesLeadMongoRepository.GetSalesLeadById(new MongoDB.Bson.ObjectId("63eb780ca34b5fad0f3bed24"));
            return true;
        }

        #endregion

        [AllowAnonymous]
        [HttpPost("InterFace/Test")]
        public async Task<int> Test()
        {
            //var list = await _customerService.Service.GetCustomerBalanceList(new FMC.HttpApi.Dtos.Recharge.CustomerBalanceListInput
            //{
            //    SystemId = CurrentRequest.BusinessSubSystemId,
            //    CustomerIds = new List<int> { 19, 201565, 201683 }
            //});

            var ss = await CurrentRequest.CurrentBusinessSubSystemAsync();

            return CurrentRequest.BusinessSubSystemId;
        }
    }
}